/*
 * @Author: fisher
 * @Date: 2024-02-19 10:05:48
 * @LastEditors: luthor luthor-li@qq.com
 * @LastEditTime: 2024-03-10 03:06:33
 * @FilePath: \allback\services\ueserverService.js
 * @Description:
 */
// const { execSync } = require('child_process')
const StreamZip = require('node-stream-zip')
const fs = require('fs-extra')
const path = require('path')
// const stream = require('stream')
const UeInstance = require('../models/ueinstanceModel')
const UefileModel = require('../models/uefileModel')
// exports.startServer = instanceConfig => {
//   const startCmd = `pm2 start ${instanceConfig}`
//   execSync(startCmd)
// }
// exports.stopServer = () => {
//   const stopCmd = `pm2 stop all`
//   execSync(stopCmd)
// }
// exports.deleteServer = () => {
//   const deleteCmd = `pm2 delete all`
//   execSync(deleteCmd)
// }
// exports.restartServer = instanceName => {
//   const restartCmd = `pm2 restart ${instanceName}`
//   execSync(restartCmd)
// }
// exports.getServerStatus = () => {
//   const listCmd = 'pm2 jlist'
//   const status = execSync(listCmd)
//   return status
// }

// 示例：启动服务器实例
// startServer('path_to_ecosystem_file_of_the_instance');
// 示例：停止服务器实例
// stopServer('InstanceName');
// 示例：删除服务器实例
// deleteServer('InstanceName');
// 示例：重启服务器实例
// restartServer('InstanceName');
// 示例：获取服务器状态
// const status = getServerStatus();
// console.log(status);

// exports.handleUefile = async (filePath, fileName) => {
//   const outputPath = path.resolve(__dirname, `../UESERVER/uefiles/${fileName}`)
//   await fs.ensureDir(outputPath) // 确保输出目录存在
//   // 创建一个 StreamZip 实例来解压文件
//   const zip = new StreamZip.async({ file: filePath })
//   // 解压缩到 outputDir 目录
//   try {
//     await zip.extract(null, outputPath)
//     await zip.close()
//     const uefile = new UefileModel({
//       name: fileName,
//       path: outputPath,
//       originalPath: filePath,
//       status: true
//     })
//     const saveUefile = await uefile.save()
//     return saveUefile
//   } catch (err) {
//     const uefile = new UefileModel({
//       name: fileName,
//       path: '',
//       originalPath: filePath,
//       status: false
//     })
//     await uefile.save()
//     throw new HttpError('解压缩错误！', 400)
//   } finally {
//     await zip.close()
//   }
// }
// exports.handleUefileSSE = async ctx => {
//   const { filePath, fileName } = ctx.query
//   try {
//     // 创建一个PassThrough流
//     const passThrough = new stream.PassThrough()
//     // 设置必要的SSE头部信息
//     ctx.set({
//       'Content-Type': 'text/event-stream', // 设置内容类型为SSE
//       Connection: 'keep-alive', // 保持连接
//       'Cache-Control': 'no-cache' // 禁用缓存
//     })
//     // 将PassThrough流绑定到Koa的响应体
//     ctx.body = passThrough
//     // 发送数据的函数
//     const sendData = data => {
//       passThrough.write(`data: ${JSON.stringify(data)}\n\n`)
//     }
//     const outputPath = path.resolve(
//       __dirname,
//       `../UESERVER/uefiles/${fileName}`
//     )
//     await fs.ensureDir(outputPath) // 确保输出目录存在
//     // 创建一个 StreamZip 实例来解压文件
//     const zip = new StreamZip.async({ file: filePath })
//     // 解压缩到 outputDir 目录
//     await zip.extract(null, outputPath)
//     await zip.close()
//     setImmediate(() => {
//       sendData({
//         status: false,
//         data: 'zip complate'
//       })
//     })
//     const uefile = new UefileModel({
//       name: fileName,
//       path: outputPath,
//       originalPath: filePath,
//       status: true
//     })
//     const saveUefile = await uefile.save()
//     setImmediate(() => {
//       sendData({
//         status: true,
//         data: saveUefile
//       })
//     })
//     // 监听请求关闭事件，清理资源
//     ctx.req.on('close', () => {
//       console.log('前端主动关闭请求')
//       passThrough.end()
//     })
//   } catch (err) {
//     throw new HttpError(err.message, 400)
//   }
// }
exports.getUefiles = async (pageSize, pageNo, name) => {
  try {
    // 设置默认的分页参数
    pageNo = parseInt(pageNo) || 1
    pageSize = parseInt(pageSize) || 10
    const skip = (pageNo - 1) * pageSize
    // 创建查询条件
    const query = {}
    if (name) {
      // 对originalFilename使用正则表达式来实现模糊搜索
      query.name = { $regex: new RegExp(name, 'i') }
    }

    // 使用查询条件，计算总记录数
    const total = await UefileModel.countDocuments(query)
    let records = []
    if (pageSize == -1) {
      // 当为pageSize为-1时全查
      records = await UefileModel.find(query)
    } else {
      // 应用查询条件，进行分页和数据提取
      records = await UefileModel.find(query)
        .sort({ createdAt: -1 })
        .skip(skip)
        .limit(pageSize)
        .exec()
    }

    return {
      total,
      records
    }
  } catch (err) {
    throw new HttpError('查询错误！', 400)
  }
}
exports.deleteUefiles = async ids => {
  try {
    // 查询是否存在已经应用的实例,保存已经发布为实例的ue工程文件id
    const deployUeIds = []
    const deployInstances = await UeInstance.find({
      projectId: { $in: ids }
    }).exec()
    deployInstances.forEach(item => {
      deployUeIds.push(item.projectId)
    })
    // 根据id查询数据
    const deleteData = await UefileModel.find({ _id: { $in: ids } }).exec()
    for (let i = 0, len = deleteData.length; i < len; i++) {
      // 当ue文件没有关联instance，则可以删除ue工程文件
      if (!deployUeIds.includes(deleteData[i]._id.toString())) {
        await fs.remove(deleteData[i].path)
        // 删除数据库记录
        await UefileModel.deleteOne({ _id: deleteData[i]._id })
      }
    }
    return deployUeIds
  } catch (err) {
    throw new HttpError(err.message, 400)
  }
}

exports.unzipUe = async (filePath, fileName, unzipUeStatus, taskId) => {
  const outputPath = path.resolve(__dirname, `../UESERVER/uefiles/${fileName}`)
  await fs.ensureDir(outputPath) // 确保输出目录存在
  // 创建一个 StreamZip 实例来解压文件
  const zip = new StreamZip.async({ file: filePath })
  // 解压缩到 outputDir 目录
  try {
    const entries = await zip.entries()
    const totalCount = Object.keys(entries).length
    let extractedCount = 0

    for (const entry of Object.values(entries)) {
      // 完整路径
      const fullPath = path.join(outputPath, entry.name)

      if (entry.isDirectory) {
        // 如果是目录则创建之
        await fs.ensureDir(fullPath)
        extractedCount++
        continue
      }

      // 确保文件的父目录存在
      await fs.ensureDir(path.dirname(fullPath))

      // 解压缩单个文件
      await zip.extract(entry.name, fullPath)
      extractedCount++
      // 更新解压进度到 unzipUeStatus
      const percent = Math.ceil((extractedCount / totalCount) * 100)
      unzipUeStatus.set(taskId, {
        status: false,
        data: percent
      })
    }

    // 创建Uefile记录并保存
    const uefile = new UefileModel({
      name: fileName,
      path: outputPath,
      originalPath: filePath,
      status: true
    })
    const saveUefile = await uefile.save()
    unzipUeStatus.set(taskId, {
      status: true,
      data: saveUefile
    })
  } catch (err) {
    console.log('解压出错', err)
    const uefile = new UefileModel({
      name: fileName,
      path: '',
      originalPath: filePath,
      status: false
    })
    await uefile.save()
    throw new HttpError('解压缩错误！', 400)
  } finally {
    await zip.close()
  }
}
